package edu.zzuli.model.dao;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.stereotype.Repository;
import org.springframework.util.Assert;

import edu.zzuli.common.MisException;
import edu.zzuli.common.Pagination;
import edu.zzuli.model.dao.hibernate.HibernateDao;
import edu.zzuli.util.MyColumnMapRowMapper;
import edu.zzuli.util.PaginationUtil;
import edu.zzuli.util.StringUtils;

/**
 * @author tianshaojie
 * @date 2010-11-11
 * @discription : 
 */

@Repository("baseDaoEntity")
public class BaseDaoEntity {
	
	@Resource
	private HibernateDao hibernateDao;
	
	@Resource
	private JdbcTemplate jdbcTemplate;

	@Resource
	private NamedParameterJdbcTemplate paraJdbcTemplate;
	
	protected final transient Log logger = LogFactory.getLog(getClass());
	
	public HibernateDao getHibernateDao() {
		return hibernateDao;
	}

	public JdbcTemplate getJdbcTemplate() {
		return jdbcTemplate;
	}

	public NamedParameterJdbcTemplate getParaJdbcTemplate() {
		return paraJdbcTemplate;
	}
	
	public BasePO save(BasePO paramBasePO) {
		Assert.notNull(paramBasePO);
		hibernateDao.save(paramBasePO);
		return paramBasePO;
	}

	public int saveAll(List<BasePO> paramList) {
		Assert.notNull(paramList);
		return hibernateDao.save(paramList);
	}

	public BasePO update(BasePO paramBasePO) {
		Assert.notNull(paramBasePO);
		hibernateDao.update(paramBasePO);
		return paramBasePO;
	}

    /**
	 * 根据主键值查询PO
	 * 
	 * @param basePO
	 * @return
	 */
	public BasePO selectSingle(BasePO basePO) {
		if (basePO == null)
			return null;
		return this.hibernateDao.selectSingle(basePO);
	}

	/**
	 * 根据sbWhere条件返回唯一PO,符合条件的有多个时返回第一个
	 * 
	 * @param basePO
	 * @param sbWhere
	 * @return
	 */
	public BasePO selectSingle(BasePO basePO, StringBuffer sbWhere) {
		try {
			BasePO resultPO = null;
			List<BasePO> listBasePO = this.hibernateDao.selectExact(basePO, sbWhere);
			if (listBasePO.size() > 0) {
				resultPO = listBasePO.get(0);
			}
			return resultPO;
		} catch (MisException e) {
			e.printStackTrace();
			throw e;
		} catch (Exception e) {
			e.printStackTrace();
			throw new MisException("[BaseDaoEntity.selectSingle]异常！", e);
		}
	}

	/**
	 * 根据sql返回唯一一条记录,符合条件的有多个时返回第一个，没有则为null
	 * @param basePO
	 * @param sbWhere
	 * @return
	 */
	@Deprecated
	public Map selectSingleMap(String sql) {
		try {
			if (StringUtils.isEmpty(sql)) {
				throw new MisException("sql语句为空！");
			}
			List<Map> listMap = this.jdbcTemplate.query(sql, MyColumnMapRowMapper.newInstance());
			if (listMap.size() > 0) {
				return listMap.get(0);
			} else {
				return null;
			}
		} catch (MisException e) {
			e.printStackTrace();
			throw e;
		} catch (Exception e) {
			e.printStackTrace();
			throw new MisException("[BaseDaoEntity.selectSingleMap]异常！", e);
		}
	}

	public Map selectSingleMap(String sql, Map map) {
		try {
			if (StringUtils.isEmpty(sql)) {
				throw new MisException("sql语句为空！");
			}
			List<Map> listMap = this.paraJdbcTemplate.query(sql, map, MyColumnMapRowMapper.newInstance());
			if (listMap.size() > 0) {
				return listMap.get(0);
			} else {
				return null;
			}
		} catch (MisException e) {
			throw e;
		} catch (Exception e) {
			throw new MisException("[BaseDaoEntity.selectSingleMap]异常！", e);
		}
	}

	public Map selectSingleMap(String sql, MapSqlParameterSource map) {
		try {
			if (StringUtils.isEmpty(sql)) {
				throw new MisException("sql语句为空！");
			}
			List<Map> listMap = this.paraJdbcTemplate.query(sql, map, MyColumnMapRowMapper.newInstance());
			if (listMap.size() > 0) {
				return listMap.get(0);
			} else {
				return null;
			}
		} catch (MisException e) {
			throw e;
		} catch (Exception e) {
			throw new MisException("[BaseDaoEntity.selectSingleMap]异常！", e);
		}
	}

	public Map selectSingleMap(String sql, BeanPropertySqlParameterSource bean) {
		try {
			if (StringUtils.isEmpty(sql)) {
				throw new MisException("sql语句为空！");
			}
			List<Map> listMap = this.paraJdbcTemplate.query(sql, bean, MyColumnMapRowMapper.newInstance());
			if (listMap.size() > 0) {
				return listMap.get(0);
			} else {
				return null;
			}
		} catch (MisException e) {
			throw e;
		} catch (Exception e) {
			throw new MisException("[BaseDaoEntity.selectSingleMap]异常！", e);
		}
	}

	@Deprecated
	public String queryForString(String sql) {
		Map<String, Object> map = this.selectSingleMap(sql);
		if (map == null) {
			return null;
		} else {
			Object obj = null;
			for (Map.Entry<String, Object> entry : map.entrySet()) {
				obj = entry.getValue();
				break;
			}
			if (obj == null) {
				return null;
			} else {
				return obj.toString();
			}
		}
	}

	public String queryForString(String sql, Map mapPara) {
		Map<String, Object> map = this.selectSingleMap(sql, mapPara);
		if (map == null) {
			return null;
		} else {
			Object obj = null;
			for (Map.Entry<String, Object> entry : map.entrySet()) {
				obj = entry.getValue();
				break;
			}
			if (obj == null) {
				return null;
			} else {
				return obj.toString();
			}
		}
	}

	public String queryForString(String sql, MapSqlParameterSource mapPara) {
		Map<String, Object> map = this.selectSingleMap(sql, mapPara);
		if (map == null) {
			return null;
		} else {
			Object obj = null;
			for (Map.Entry<String, Object> entry : map.entrySet()) {
				obj = entry.getValue();
				break;
			}
			if (obj == null) {
				return null;
			} else {
				return obj.toString();
			}
		}
	}

	public String queryForString(String sql, BeanPropertySqlParameterSource bean) {
		Map<String, Object> map = this.selectSingleMap(sql, bean);
		if (map == null) {
			return null;
		} else {
			Object obj = null;
			for (Map.Entry<String, Object> entry : map.entrySet()) {
				obj = entry.getValue();
				break;
			}
			if (obj == null) {
				return null;
			} else {
				return obj.toString();
			}
		}
	}

	@Deprecated
	public List queryForList(String sql) {
		try {
			if (StringUtils.isEmpty(sql)) {
				throw new MisException("sql语句为空！");
			}
			return this.jdbcTemplate.query(sql, MyColumnMapRowMapper.newInstance());
		} catch (MisException e) {
			e.printStackTrace();
			throw e;
		} catch (Exception e) {
			e.printStackTrace();
			throw new MisException("[BaseDaoEntity.queryForList]异常！", e);
		}
	}

	public List queryForList(String sql, Map map) {
		try {
			if (StringUtils.isEmpty(sql)) {
				throw new MisException("sql语句为空！");
			}
			if (map == null) {
				throw new MisException("查询参数为null！");
			}
			return this.paraJdbcTemplate.query(sql, map, MyColumnMapRowMapper.newInstance());
		} catch (MisException e) {
			throw e;
		} catch (Exception e) {
			throw new MisException("[BaseDaoEntity.queryForList]异常！", e);
		}
	}

	public List queryForList(String sql, MapSqlParameterSource paramMap) {
		try {
			if (StringUtils.isEmpty(sql)) {
				throw new MisException("sql语句为空！");
			}
			if (paramMap == null) {
				throw new MisException("查询参数为null！");
			}
			return this.paraJdbcTemplate.query(sql, paramMap, MyColumnMapRowMapper.newInstance());
		} catch (MisException e) {
			throw e;
		} catch (Exception e) {
			throw new MisException("[BaseDaoEntity.queryForList]异常！", e);
		}
	}

	public List queryForList(String sql, BeanPropertySqlParameterSource bean) {
		try {
			if (StringUtils.isEmpty(sql)) {
				throw new MisException("sql语句为空！");
			}
			if (bean == null) {
				throw new MisException("查询参数为null！");
			}
			return this.paraJdbcTemplate.query(sql, bean, MyColumnMapRowMapper.newInstance());
		} catch (MisException e) {
			throw e;
		} catch (Exception e) {
			throw new MisException("[BaseDaoEntity.queryForList]异常！", e);
		}
	}

	/** 
	 *@author tianshaojie
	 *@date 2008-10-11
	 *@discription : (JDBC)增加记录
	 *@param po void
	 */
	public void jdbcInsert(BasePO po) {
		this.getJdbcTemplate().update(new StringBuffer("insert into ").append(po.getStrTableName()).append(" (").append(po.getStrFields()).append(") values (").append(po.getStrInsValues()).append(")").toString());
	}

	/** 
	 *@author tianshaojie
	 *@date 2008-10-11
	 *@discription : (JDBC)修改记录
	 *@param po void
	 */
	public void jdbcUpdate(BasePO po) {
		this.getJdbcTemplate().update(new StringBuffer("update ").append(po.getStrTableName()).append(" set ").append(po.getStrUpdValues()).append(" where ").append(po.getStrKeyWhere()).toString());
	}
	/**
	 * @author tianshaojie
	 * @discription : (JDBC)批量更新
	 * @param listPO
	 */
	public void jdbcBatchUpdate(List<BasePO> listPO) {
		List<String> listBatchSql = new ArrayList<String>();
		for (BasePO po:listPO) {
			listBatchSql.add(new StringBuffer("update ").append(po.getStrTableName()).append(" set ").append(po.getStrUpdValues()).append(" where ").append(po.getStrKeyWhere()).toString());
		}
		this.jdbcTemplate.batchUpdate(listBatchSql.toArray(new String[] {}));
	}

	/** 
	 *@author tianshaojie
	 *@date 2008-10-11
	 *@discription : (JDBC)删除记录
	 *@param po void
	 */
	public void jdbcDelete(BasePO po) {
		this.getJdbcTemplate().update(new StringBuffer("delete ").append(po.getStrTableName()).append(" where ").append(po.getStrKeyWhere()).toString());
	}
	
	/**
	 * @author tianshaojie
	 * @date 2011-7-16
	 * @discription : (JDBC)通过SQL获得分页结果集
	 * @param sql
	 * @param pagination
	 * @return List<Map<String,Object>>
	 */
	public List<Map<String, Object>> selectSplit(String sql, Pagination pagination) {
		StringBuffer strCountSql = new StringBuffer("select count(*) from (").append(sql).append(")");
		int count = jdbcTemplate.queryForInt(strCountSql.toString());
		pagination.setTotalRows(count);//总记录条数返回给Pagination类
		String strSql = PaginationUtil.getLimitString(sql, pagination.getCurrentPage(), pagination.getPageRowBegin(), pagination.getPageRowEnd());
		return jdbcTemplate.query(strSql, MyColumnMapRowMapper.newInstance());
	}

	/**
	 * @author tianshaojie
	 * @date 2011-7-16
	 * @discription : (JDBC)通过带参数SQL获得分页结果集
	 * @param sql
	 * @param parameterSource
	 * @param pagination
	 * @return List<Map<String,Object>>
	 */
	public List<Map<String, Object>> selectSplit(String sql, SqlParameterSource parameterSource, Pagination pagination) {
		StringBuffer strCountSql = new StringBuffer("select count(*) from (").append(sql).append(")");
		int count = paraJdbcTemplate.queryForInt(strCountSql.toString(), parameterSource);
		pagination.setTotalRows(count);//总记录条数返回给Pagination类
		String strSql = PaginationUtil.getLimitString(sql, pagination.getCurrentPage(), pagination.getPageRowBegin(), pagination.getPageRowEnd());
		return paraJdbcTemplate.query(strSql, parameterSource, MyColumnMapRowMapper.newInstance());
	}

	/**
	 * @author tianshaojie
	 * @date 2011-7-16
	 * @discription : 通过list获得分页结果集（用于无法通过SQL直接得到分页结果的情况）
	 * @param list
	 * @param pagination
	 * @return List
	 */
	public List selectSplit(List list, Pagination pagination) {
		pagination.setTotalRows(list == null ? 0 : list.size());
		List result = new ArrayList();
		if (list == null) {
			return null;
		} else {
			for (int i = pagination.getPageRowBegin(); 0 <= i && i < pagination.getPageRowEnd(); i++) {
				result.add(list.get(i));
			}
		}
		return result;
	}
}
